<!DOCTYPE html>
<html lang="en" class="dark">
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>高能的博客</title>
    <!-- <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet"> -->
    
<link rel="stylesheet" href="/css/root.css">

    
<script src="/js/tailwind.js"></script>

    
<link rel="stylesheet" href="/css/tailwind.min.css">

    <!-- <script src="https://cdn.tailwindcss.com"></script> -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>    
    <style>
        .isLoading {
            filter: blur(10px);
            overflow: hidden;
        }
        .finishLoading{
            filter: blur(0);
            overflow: hidden;
        }
    </style>

    <script src="js/index.js" defer></script>
<meta name="generator" content="Hexo 6.1.0"></head>
    <body class="bg-gray-200 dark:bg-gray-900">
        <style>
            html,body{width: 100%;height: 100%;margin: 0;padding: 0;}
        </style>
        <div class="
            container
            m-auto
            flex
            sm:w-11/12
            md:w-11/12
            lg:w-11/12
            xl:w-3/4
            2xl:w-3/4
            pt-4
        ">
            
<link rel="stylesheet" href="/css/components/author.css">

<script>
    $('.menu li a').on('click', (e)=>{
        toggleMenu()
        e.preventDefault();
    })
</script>
<style>
    .side-menu{
        transition: all .5s ease;
    }
    .isHidden{
        left: -200px;
    }
    .isShow{
        left: 0;
        display: block;
    }
    .masks{
        display: none;
    }
    .mask{
        background: black;
        opacity: .3;
    }
</style>
<div class="
    flex
    lg:hidden
    xl:hidden
    2xl:hidden
"
    style="width: 50px;height: 50px;border-radius: 100%; background: rgb(36, 236, 103); position: fixed; bottom: 1em; left: 1em;"
    onclick="toggleMenu()"
>
    <svg style="margin: auto;"
        xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd" />
    </svg>
</div>
<div 
class="
    masks
    sm:block
    md:block
    lg:hidden
    xl:hidden
    2xl:hidden
    w-screen
    h-screen
    sm: fixed
    md: fixed
    inset-0
" onclick="toggleMenu()">
</div>
<div class="
        bg-gray-200
        dark:bg-gray-900
        fixed
        side-menu
        isHidden
        sm:block
        md:block
        lg:hidden
        xl:hidden
        2xl:hidden
        sm:fixed
        md:fixed
        xl:static
        2xl:static
        h-screen
        top-0
        left-0
">
    <div
        class="
        author-block
        bg-gray-100
        dark:bg-gray-800
        "
        style="margin-top: 1em;"
    >
        <img src="/img/author_avatar.jpg" alt="" />
        <div class="author-block-description">
            <p class="
                m-auto
                text-center
                mt-2
                w-4/5
                truncate
                dark:text-gray-100
            ">高能</p>
            <p class="
                m-auto
                text-center
                mt-2
                w-4/5
                truncate
                text-sm
                dark:text-gray-200
            ">我不知道说什么就随便打一点吧</p>
        </div>
    </div>
    <div
        class="
            menu
        "
        style="padding: 0;"
    >
        <div 
            class="
                w-full
                bg-gray-100
                dark:bg-gray-800
        "
        >
            <ul class="
                text-center
            "
            >
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                "
                >
                    <a href="/"
                       class="menu-item-link hover:text-blue-700"
                    >
                        首页
                    </a>
                </li>
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                "
                >
                    <a href="/categories"
                       class="menu-item-link hover:text-blue-700"
                    >
                        归档
                    </a>
                </li>
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                "
                >
                    <a href="/Link"
                       class="menu-item-link hover:text-blue-700"
                    >
                        朋友们
                    </a>
                </li>
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                "
                >
                    <a href="/about"
                       class="menu-item-link hover:text-blue-700"
                    >
                        关于我
                    </a>
                </li>
                
            </ul>
        </div>
    </div>
    <div class="
        closeMenu
        w-full
        flex
    "
        style="
            height: 50px; position: absolute; bottom: 5px;justify-content: center;
        "
    >
        <div 
            class="
                close
                w-10/12
                dark: bg-gray-600
                flex
                text-gray-200
            "
            style="
                justify-content: center;
                align-items: center;
            "
            onclick="
                toggleMenu()
            "
        >
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
                <path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd" />
            </svg>
        </div>
    </div>
</div>
<div
    class="
        author-wrapper
        hidden
        flex-shrink-0
        sm:hidden
        md:hidden
        lg:block
        xl:block
        2xl:block
    "
>
    <div class="
        author-block
        bg-gray-100
        rounded-md
        shadow
        mb-1
        dark:bg-gray-800
    ">
        <img src="/img/author_avatar.jpg" alt="" />
        <div class="author-block-description">
            <p class="
                m-auto
                text-center
                mt-2
                w-4/5
                truncate
                dark:text-gray-100
            ">高能</p>
            <p class="
                m-auto
                text-center
                mt-2
                w-4/5
                truncate
                text-sm
                dark:text-gray-200
            ">我不知道说什么就随便打一点吧</p>
        </div>
    </div>
    <div
        class="
            menu
            mt-4
        "
    >
        <div 
            class="
                w-full
                bg-gray-100
                rounded-md
                shadow
                mt-4
                dark:bg-gray-800
        "
        >
            <ul class="
                text-center
            "
            >
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                " onclick="toggleMenu()"
                >
                    <a href="/"
                       class="menu-item-link hover:text-blue-700"
                       
                    >
                        首页
                    </a>
                </li>
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                " onclick="toggleMenu()"
                >
                    <a href="/categories"
                       class="menu-item-link hover:text-blue-700"
                       
                    >
                        归档
                    </a>
                </li>
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                " onclick="toggleMenu()"
                >
                    <a href="/Link"
                       class="menu-item-link hover:text-blue-700"
                       
                    >
                        朋友们
                    </a>
                </li>
                
                <li class="
                    menu-item
                    pt-1
                    pb-1
                    dark:text-gray-200
                " onclick="toggleMenu()"
                >
                    <a href="/about"
                       class="menu-item-link hover:text-blue-700"
                       
                    >
                        关于我
                    </a>
                </li>
                
            </ul>
        </div>
    </div>
</div>
            <div id="view" class="w-full ">
                
<link rel="stylesheet" href="/css/components/vs2015.min.css">


<link rel="stylesheet" href="/css/components/post.css">

<div class="post w-full">
    <div
        class="
            post-content-wrapper
            mb-2
            rounded-lg
            w-full
            m-auto
            sm:w-full
            md:w-full
            bg-gray-100
            p-4
            shadow
            dark:bg-gray-800
    "
    >
        <div class="post-content w-full">
            <a class="back"
               href='javascript:void(0)'
               onclick="window.history.go(-1)">返回</a>
            <br />
            <h1 id="一文搞懂this指向"><a href="#一文搞懂this指向" class="headerlink" title="一文搞懂this指向"></a>一文搞懂this指向</h1><p>this指向在ES6之前的时代一直是一个让人很头疼的事情，之所以头疼是因为ES6之前没有箭头函数，导致运行的时候，程序跑着跑着就把this丢了<del>(this:哈哈，我走啦~)</del>。</p>
<p>虽然ES6出来了，使用箭头函数可以让开发者绕开this指向这个东西(<del>奇行种</del>)</p>
<h2 id="this的前世今生"><a href="#this的前世今生" class="headerlink" title="this的前世今生"></a>this的前世今生</h2><p>每一个函数都有一个<code>this</code>形参，不过是隐藏的。当直接调用函数，而没有限定时this便会只想全局作用域.this本质就是对函数调用的一个表现。我们来看一个《JavaScript 20年》中，对this举的例子</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">setX</span>(<span class="params">x_</span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">x</span> = x_</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> obj = <span class="keyword">new</span> <span class="title class_">Object</span>;</span><br><span class="line">obj.<span class="title function_">setX</span>(<span class="number">114514</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">x</span>) <span class="comment">// 114514</span></span><br><span class="line"><span class="title function_">setX</span>(<span class="number">1919110</span>)</span><br><span class="line">consoele.<span class="title function_">log</span>(x) <span class="comment">// 1919110</span></span><br></pre></td></tr></table></figure>

<h2 id="this的四种指向"><a href="#this的四种指向" class="headerlink" title="this的四种指向"></a>this的四种指向</h2><p>this通常存在三种指向</p>
<h3 id="在函数中"><a href="#在函数中" class="headerlink" title="在函数中"></a>在函数中</h3><p>在函数中，this通常指向于调用函数时的环境。我们来看一个例子</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> age = <span class="number">18</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">age</span>); <span class="comment">// 18</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fn</span>();</span><br></pre></td></tr></table></figure>

<p>不过值得注意的是，我们不能将<code>var</code>改为<code>let</code>或<code>const</code>，这是因为<code>let</code>与<code>const</code>不会产生一个全局对象。</p>
<p>之所以如此是因为<code>this</code>永远指向于函数运行时的环境。如果对这个概念不是很理解，我们可以看下一个图片</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Window&#123;</span><br><span class="line">    age = 18;</span><br><span class="line">    fn&#123;</span><br><span class="line">        // ...</span><br><span class="line">    &#125;</span><br><span class="line">    fn() &lt;- 此时我们运行的环境是在window环境下，所以this指向的就是window</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h3 id="在dom事件中"><a href="#在dom事件中" class="headerlink" title="在dom事件中"></a>在dom事件中</h3><p>如果dom事件中传入的参数是使用function关键字声明的匿名函数，那么this将会指向window.如果使用了<code>bind</code>,<code>apply</code>,<code>call</code>等函数，那么将会指向传入的对象。否则默认情况下一般指向的是dom对象</p>
<div 
style="width:100px;height:100px;background:red;margin:auto;line-height:100px;text-align:center;"
onclick="alert(`你单机了:${this.tagName}元素`)">
单击我
</div>

<p>假如onclick时间传入的是一个匿名函数，那么this指向的将会是window</p>
<div 
style="width:100px;height:100px;background:red;margin:auto;line-height:100px;text-align:center;"
onclick="
    (function(){alert(`this===window:${this===window}`)})()
">
    单击我
</div>

<h3 id="在对象中"><a href="#在对象中" class="headerlink" title="在对象中"></a>在对象中</h3><p>在对象中，this默认指向的是对象</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">    <span class="attr">x</span>: <span class="number">21</span>,</span><br><span class="line">    <span class="attr">fn</span>: <span class="keyword">function</span> (<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(obj)  <span class="comment">// &#123;x: 21, fn: ƒ&#125;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="title function_">fn</span>();</span><br></pre></td></tr></table></figure>
<p>上例的环境图入下所示</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Window&#123;</span><br><span class="line">    obj&#123;</span><br><span class="line">        fn</span><br><span class="line">    &#125;</span><br><span class="line">    obj.fn(); &lt;- fn在obj中，所以fn的this指向的是obj</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>如果我们将<code>obj.fn</code>这个函数赋值给其他变量，那么this指向的是window</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">    <span class="attr">x</span>: <span class="number">21</span>,</span><br><span class="line">    <span class="attr">fn</span>: <span class="keyword">function</span> (<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> f = obj.<span class="property">fn</span></span><br><span class="line"><span class="title function_">f</span>() <span class="comment">// window</span></span><br></pre></td></tr></table></figure>

<p>我们可以认为变量<code>f</code>对<code>obj.fn</code>进行了引用赋值，同时调用<code>f()</code>时上下文环境处于window。所以this指向的是window.</p>
<p>如果您无法理解this的动态切换，我们来做下面这个练习</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">x</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Obj1</span> = &#123;</span><br><span class="line">    <span class="attr">x</span>: <span class="number">1</span>,</span><br><span class="line">    <span class="attr">f</span>: f</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Obj2</span> = &#123;</span><br><span class="line">  <span class="attr">x</span>:<span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Obj2</span>.<span class="property">f</span> = <span class="title class_">Obj1</span>.<span class="property">f</span>; <span class="comment">// 将Obj1中的f赋值给Obj2中，那么this将会强行指向Obj2</span></span><br><span class="line"><span class="title class_">Obj1</span>.<span class="title function_">f</span>();</span><br><span class="line"><span class="title class_">Obj2</span>.<span class="title function_">f</span>(); </span><br></pre></td></tr></table></figure>

<h3 id="在构造函数中"><a href="#在构造函数中" class="headerlink" title="在构造函数中"></a>在构造函数中</h3><p>假如我们存在一个类<code>Person</code>,实例化该类后产生的实例为<code>p</code>,那么<code>Person</code>中的this将会强制指向为<code>p</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">x</span> = <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>(); <span class="comment">// Person中的this指向该实例对象p</span></span><br></pre></td></tr></table></figure>

<h2 id="this丢失"><a href="#this丢失" class="headerlink" title="this丢失"></a>this丢失</h2><p>如果this在本应该执行对象或者函数的时候，指向了window。那么可以成为this丢失。我们可以通过显式绑定和箭头函数来修复this丢失问题</p>
<h3 id="显式绑定"><a href="#显式绑定" class="headerlink" title="显式绑定"></a>显式绑定</h3><p>我们可以使用<code>bind</code>, <code>call</code>, <code>apply</code>来对函数进行this的绑定。</p>
<h3 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h3><p>箭头函数是ES6新增的一个特性，如果我们使用箭头函数来声明一个函数的话，该函数不会存在自身的this指向，而是默认指向上一级。例如</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x = <span class="number">3</span>;</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">x</span>: <span class="number">2</span>,</span><br><span class="line">    <span class="attr">fn</span>: <span class="function">()=&gt;</span>&#123;<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">x</span>)&#125;</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="title function_">fn</span>() <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>

<p>同时箭头函数也是一个十分悟行我素的一个特性(<del>小东西</del>).显式绑定对箭头函数无效，依旧指向上级环境</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x = <span class="number">3</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">fn</span> = (<span class="params"></span>)=&gt;&#123;<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">x</span>)&#125;;</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">    <span class="attr">x</span>: <span class="number">2</span>,</span><br><span class="line">    <span class="attr">fn</span>: fn</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="property">fn</span>.<span class="title function_">call</span>(obj) <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>
        </div>
    </div>
</div>
<script src='https://unpkg.com/valine/dist/Valine.min.js'></script>
<style>
#vcomments{
    background:white;
    margin-top:15px;
}
</style>
<div 
    id="vcomments"
    class="
        bg-gray-100
        dark:bg-gray-800
    "
></div>
<script>
    new Valine({
        el: '#vcomments',
        appId: 'AtqlqVzfRkyMHAuApkDSI4PU-gzGzoHsz',
        appKey: 'XkCJLequPVpjBIYkPBLyouA3'
    })
</script>

            </div>
        </div>
    </body>
</html>
